#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""量子金融分析系统 - 主窗口
应用程序的主入口点，负责创建和管理主界面"""

import sys
import os
import json
from datetime import datetime
import time
import webbrowser
from PyQt5.QtWidgets import (
    QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QTabWidget,
    QLabel, QPushButton, QTableWidget, QTableWidgetItem, QHeaderView,
    QLineEdit, QComboBox, QSpinBox, QDoubleSpinBox, QMessageBox, QSplitter,
    QGroupBox, QFormLayout, QDateTimeEdit, QTextBrowser, QDockWidget
)
from PyQt5.QtGui import QFont, QIcon, QColor, QBrush
from PyQt5.QtCore import Qt, QTimer, QDateTime

# 添加项目根目录到系统路径
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

from utils import Logger, FileUtils
from utils.auto_update.update_manager import UpdateManager
from utils.anti_detection.detection_manager import DetectionManager
from api_integration import APIIntegration
from trade_executor import TradeExecutor
from risk_manager import RiskManager
from analysis_module import ProductAnalysis

class MainWindow(QMainWindow):
    """主窗口类"""
    
    def __init__(self, platform=None, account_name=None, account_id=None):
        """初始化主窗口"""
        super().__init__()
        
        # 保存平台、账户名称和账户ID
        self.platform = platform
        self.account_name = account_name
        self.account_id = account_id  # 新增：保存账户ID用于直接登录
        
        # 初始化核心组件
        self.api_integration = APIIntegration()
        self.risk_manager = RiskManager()
        self.product_analysis = ProductAnalysis(self.api_integration)
        
        # 暂时不初始化交易执行器，等待账户列表加载完成后在on_account_changed中初始化
        self.trade_executor = None
        
        # 初始化自动升级系统
        self.update_manager = UpdateManager()
        
        # 初始化反侦查系统
        self.detection_manager = DetectionManager()
        
        # 配置UI
        self.setWindowTitle("量子金融分析系统")
        self.setup_ui()
        
        # 加载布局配置
        self.load_layout_config()
        
        # 如果提供了平台和账户名称，创建默认账户或直接登录
        if platform and account_name:
            self._create_default_account(platform, account_name, account_id)
        
        # 初始化数据
        self.init_data()
        
        # 设置定时器，用于刷新行情数据
        self.market_data_timer = QTimer(self)
        self.market_data_timer.timeout.connect(self.update_market_data)
        self.market_data_timer.start(30000)  # 每30秒刷新一次
        
        # 启动自动升级系统
        self.update_manager.start()
        
        # 启动反侦查系统
        self.detection_manager.start_protection()
        
        Logger.log_info("主窗口初始化完成")
    
    def _create_default_account(self, platform, account_name, account_id=None):
        """创建默认账户或使用指定的account_id登录"""
        from utils.account_manager import account_manager
        
        try:
            # 如果提供了account_id，直接尝试使用该账户
            if account_id:
                Logger.log_info(f"尝试使用指定的账户ID登录: {account_id}")
                # 检查账户是否存在
                accounts = account_manager.get_all_accounts()
                account_exists = False
                for acc in accounts:
                    if acc.get('account_id') == account_id:
                        account_exists = True
                        break
                
                if account_exists:
                    # 切换到指定账户
                    account_manager.switch_account(account_id)
                    self.api_integration.switch_account(account_id)
                    Logger.log_info(f"成功切换到账户ID: {account_id}")
                    return
                else:
                    # 账户不存在，创建新账户
                    Logger.log_info(f"指定的账户ID不存在，创建新账户: {account_name}")
            
            # 检查是否已经存在相同名称的账户
            accounts = account_manager.get_all_accounts()
            existing_account = None
            
            for account in accounts:
                if account['account_name'] == account_name and account['platform'] == platform:
                    existing_account = account
                    break
            
            if existing_account:
                # 如果账户已存在，直接使用
                Logger.log_info(f"使用已存在的账户: {account_name}")
                # 如果账户有ID，切换到该账户
                if 'account_id' in existing_account:
                    account_manager.switch_account(existing_account['account_id'])
                    self.api_integration.switch_account(existing_account['account_id'])
                return
            
            # 创建新的默认账户
            api_key = "default_api_key"
            api_secret = "default_api_secret"
            
            # 添加账户
            account_id = account_manager.add_account(
                platform=platform,
                account_name=account_name,
                api_key=api_key,
                api_secret=api_secret,
                description=f"默认账户 - {platform}"
            )
            
            if account_id:
                Logger.log_info(f"成功创建默认账户: {account_name}")
                # 切换到新创建的账户
                self.api_integration.switch_account(account_id)
            else:
                Logger.log_error(f"创建默认账户失败: {account_name}")
        except Exception as e:
            Logger.log_error(f"创建默认账户时发生错误: {str(e)}")
    
    def setup_ui(self):
        """设置用户界面"""
        # 创建中央部件
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        
        # 主布局
        main_layout = QVBoxLayout(central_widget)
        main_layout.setContentsMargins(10, 10, 10, 10)
        main_layout.setSpacing(10)
        
        # 创建选项卡
        self.tab_widget = QTabWidget()
        
        # 添加各个功能选项卡
        self.market_tab = self.create_market_tab()
        
        # 如果提供了账户ID，先只添加行情选项卡，其他选项卡稍后根据登录状态动态添加
        if self.account_id:
            # 将选项卡添加到选项卡小部件
            self.tab_widget.addTab(self.market_tab, "行情")
            
            # 添加状态栏信息
            self.statusBar().showMessage(f"欢迎使用量子金融分析系统 - 直接登录模式: {self.platform}, 账户: {self.account_name}")
        else:
            self.trade_tab = self.create_trade_tab()
            self.portfolio_tab = self.create_portfolio_tab()
            self.risk_tab = self.create_risk_tab()
            self.account_tab = self.create_account_tab()
            
            # 将选项卡添加到选项卡小部件
            self.tab_widget.addTab(self.market_tab, "行情")
            self.tab_widget.addTab(self.trade_tab, "交易")
            self.tab_widget.addTab(self.portfolio_tab, "持仓")
            self.tab_widget.addTab(self.risk_tab, "风险")
            self.tab_widget.addTab(self.account_tab, "账户")
            
            # 添加状态栏信息
            self.statusBar().showMessage("就绪")
        
        # 将选项卡小部件添加到主布局
        main_layout.addWidget(self.tab_widget)
    
    def create_market_tab(self):
        """创建行情选项卡"""
        tab = QWidget()
        layout = QVBoxLayout(tab)
        
        # 搜索框和按钮
        search_layout = QHBoxLayout()
        
        # 添加产品类型选择器
        self.product_type_selector = QComboBox()
        self.product_type_selector.addItem("股票", "stock")
        self.product_type_selector.addItem("基金", "fund")
        self.product_type_selector.addItem("债券", "bond")
        self.product_type_selector.addItem("期货", "future")
        self.product_type_selector.currentIndexChanged.connect(self.on_product_type_changed)
        
        self.stock_code_input = QLineEdit()
        self.stock_code_input.setPlaceholderText("输入代码，如：SH600000")
        
        search_button = QPushButton("查询")
        search_button.clicked.connect(self.query_stock)
        
        # 添加分析报告按钮
        generate_report_button = QPushButton("获取分析报告")
        generate_report_button.clicked.connect(self.generate_product_analysis)
        
        search_layout.addWidget(QLabel("产品类型："))
        search_layout.addWidget(self.product_type_selector)
        search_layout.addWidget(self.stock_code_input)
        search_layout.addWidget(search_button)
        search_layout.addWidget(generate_report_button)
        
        # 行情表格
        self.market_table = QTableWidget()
        self.market_table.setColumnCount(11)
        self.market_table.setHorizontalHeaderLabels([
            "代码", "名称", "当前价", "涨跌幅", "开盘价", "最高价", 
            "最低价", "成交量(万)", "成交额(万)", "换手率", "更新时间"
        ])
        
        # 设置表格自适应
        header = self.market_table.horizontalHeader()
        for i in range(self.market_table.columnCount()):
            header.setSectionResizeMode(i, QHeaderView.Stretch)
        
        # 添加到布局
        layout.addLayout(search_layout)
        layout.addWidget(self.market_table)
        
        return tab
    
    def create_trade_tab(self):
        """创建交易选项卡"""
        tab = QWidget()
        layout = QHBoxLayout(tab)
        
        # 左侧交易表单
        form_group = QGroupBox("交易委托")
        form_layout = QFormLayout()
        
        self.trade_stock_code = QLineEdit()
        self.trade_order_type = QComboBox()
        self.trade_order_type.addItems(["买入", "卖出"])
        self.trade_quantity = QSpinBox()
        self.trade_quantity.setRange(1, 1000000)
        self.trade_price = QDoubleSpinBox()
        self.trade_price.setRange(0.01, 1000.0)
        self.trade_price.setDecimals(2)
        
        # 添加到表单
        form_layout.addRow("股票代码:", self.trade_stock_code)
        form_layout.addRow("交易类型:", self.trade_order_type)
        form_layout.addRow("交易数量:", self.trade_quantity)
        form_layout.addRow("交易价格:", self.trade_price)
        
        # 下单按钮
        order_button = QPushButton("提交订单")
        order_button.clicked.connect(self.submit_order)
        form_layout.addRow(order_button)
        
        form_group.setLayout(form_layout)
        
        # 右侧订单列表
        orders_group = QGroupBox("订单列表")
        orders_layout = QVBoxLayout()
        
        self.orders_table = QTableWidget()
        self.orders_table.setColumnCount(7)
        self.orders_table.setHorizontalHeaderLabels([
            "订单ID", "股票代码", "交易类型", "数量", "价格", "状态", "创建时间"
        ])
        
        # 设置表格自适应
        header = self.orders_table.horizontalHeader()
        for i in range(self.orders_table.columnCount()):
            header.setSectionResizeMode(i, QHeaderView.Stretch)
        
        # 取消订单按钮
        cancel_button = QPushButton("取消选中订单")
        cancel_button.clicked.connect(self.cancel_selected_order)
        
        # 添加到布局
        orders_layout.addWidget(self.orders_table)
        orders_layout.addWidget(cancel_button)
        
        orders_group.setLayout(orders_layout)
        
        # 分割器
        splitter = QSplitter(Qt.Horizontal)
        splitter.addWidget(form_group)
        splitter.addWidget(orders_group)
        splitter.setSizes([300, 600])
        
        layout.addWidget(splitter)
        
        return tab
    
    def create_portfolio_tab(self):
        """创建持仓选项卡"""
        tab = QWidget()
        layout = QVBoxLayout(tab)
        
        # 持仓表格
        self.portfolio_table = QTableWidget()
        self.portfolio_table.setColumnCount(9)
        self.portfolio_table.setHorizontalHeaderLabels([
            "股票代码", "股票名称", "持仓数量", "持仓成本", "当前价", 
            "市值", "浮动盈亏", "盈亏比例", "更新时间"
        ])
        
        # 设置表格自适应
        header = self.portfolio_table.horizontalHeader()
        for i in range(self.portfolio_table.columnCount()):
            header.setSectionResizeMode(i, QHeaderView.Stretch)
        
        # 刷新按钮
        refresh_button = QPushButton("刷新持仓")
        refresh_button.clicked.connect(self.refresh_portfolio)
        
        # 添加到布局
        button_layout = QHBoxLayout()
        button_layout.addWidget(refresh_button)
        button_layout.addStretch()
        
        layout.addLayout(button_layout)
        layout.addWidget(self.portfolio_table)
        
        return tab
    
    def create_risk_tab(self):
        """创建风险选项卡"""
        tab = QWidget()
        layout = QVBoxLayout(tab)
        
        # 风险规则设置
        risk_group = QGroupBox("风险控制规则")
        risk_layout = QFormLayout()
        
        self.max_position_per_stock = QDoubleSpinBox()
        self.max_position_per_stock.setRange(0, 1000000)
        self.max_position_per_stock.setSuffix(" 元")
        self.max_single_order = QDoubleSpinBox()
        self.max_single_order.setRange(0, 1000000)
        self.max_single_order.setSuffix(" 元")
        self.daily_trading_limit = QDoubleSpinBox()
        self.daily_trading_limit.setRange(0, 10000000)
        self.daily_trading_limit.setSuffix(" 元")
        self.max_position_percentage = QDoubleSpinBox()
        self.max_position_percentage.setRange(0, 1)
        self.max_position_percentage.setDecimals(2)
        self.max_position_percentage.setSuffix(" %")
        
        # 添加到表单
        risk_layout.addRow("单只股票最大持仓金额:", self.max_position_per_stock)
        risk_layout.addRow("单笔交易最大金额:", self.max_single_order)
        risk_layout.addRow("单日交易总限额:", self.daily_trading_limit)
        risk_layout.addRow("单只股票最大持仓比例:", self.max_position_percentage)
        
        # 保存按钮
        save_risk_button = QPushButton("保存风险设置")
        save_risk_button.clicked.connect(self.save_risk_settings)
        risk_layout.addRow(save_risk_button)
        
        risk_group.setLayout(risk_layout)
        
        # 风险评估结果
        evaluation_group = QGroupBox("风险评估历史")
        evaluation_layout = QVBoxLayout()
        
        self.risk_evaluation_table = QTableWidget()
        self.risk_evaluation_table.setColumnCount(5)
        self.risk_evaluation_table.setHorizontalHeaderLabels([
            "股票代码", "交易类型", "交易金额", "风险等级", "评估结果"
        ])
        
        # 设置表格自适应
        header = self.risk_evaluation_table.horizontalHeader()
        for i in range(self.risk_evaluation_table.columnCount()):
            header.setSectionResizeMode(i, QHeaderView.Stretch)
        
        evaluation_layout.addWidget(self.risk_evaluation_table)
        evaluation_group.setLayout(evaluation_layout)
        
        # 添加到主布局
        layout.addWidget(risk_group)
        layout.addWidget(evaluation_group)
        
        # 加载风险设置
        self.load_risk_settings()
        
        return tab
    
    def create_account_tab(self):
        """创建账户选项卡"""
        tab = QWidget()
        layout = QVBoxLayout(tab)
        
        # 账户选择和管理区域
        account_management_group = QGroupBox("账户管理")
        account_management_layout = QHBoxLayout()
        
        # 账户列表
        self.account_list = QComboBox()
        self.account_list.currentIndexChanged.connect(self.on_account_changed)
        
        # 账户管理按钮
        buttons_layout = QVBoxLayout()
        self.add_account_button = QPushButton("添加账户")
        self.add_account_button.clicked.connect(self.add_account)
        self.remove_account_button = QPushButton("删除账户")
        self.remove_account_button.clicked.connect(self.remove_account)
        self.edit_account_button = QPushButton("编辑账户")
        self.edit_account_button.clicked.connect(self.edit_account)
        
        buttons_layout.addWidget(self.add_account_button)
        buttons_layout.addWidget(self.remove_account_button)
        buttons_layout.addWidget(self.edit_account_button)
        buttons_layout.addStretch()
        
        account_management_layout.addWidget(self.account_list, 1)
        account_management_layout.addLayout(buttons_layout)
        account_management_group.setLayout(account_management_layout)
        
        # 当前账户信息显示
        current_account_info_label = QLabel("当前账户: ")
        self.current_account_display = QLabel("default")
        account_display_layout = QHBoxLayout()
        account_display_layout.addWidget(current_account_info_label)
        account_display_layout.addWidget(self.current_account_display)
        account_display_layout.addStretch()
        
        # 先初始化所有UI元素，再刷新账户列表
        self.refresh_account_list()
        
        # 账户信息表单
        account_group = QGroupBox("账户信息")
        account_layout = QFormLayout()
        
        self.total_asset = QLabel("0.00 元")
        self.available_cash = QLabel("0.00 元")
        self.market_value = QLabel("0.00 元")
        self.total_profit = QLabel("0.00 元")
        self.profit_rate = QLabel("0.00 %")
        
        # 设置标签样式
        font = QFont()
        font.setBold(True)
        self.total_asset.setFont(font)
        self.available_cash.setFont(font)
        self.market_value.setFont(font)
        self.total_profit.setFont(font)
        self.profit_rate.setFont(font)
        
        # 添加到表单
        account_layout.addRow("总资产:", self.total_asset)
        account_layout.addRow("可用资金:", self.available_cash)
        account_layout.addRow("持仓市值:", self.market_value)
        account_layout.addRow("总盈亏:", self.total_profit)
        account_layout.addRow("盈亏率:", self.profit_rate)
        
        account_group.setLayout(account_layout)
        
        # API配置
        api_group = QGroupBox("API配置")
        api_layout = QFormLayout()
        
        self.api_key_input = QLineEdit()
        self.api_secret_input = QLineEdit()
        self.api_secret_input.setEchoMode(QLineEdit.Password)
        
        # 平台选择
        platform_layout = QHBoxLayout()
        platform_label = QLabel("交易平台:")
        self.platform_selector = QComboBox()
        self.platform_selector.setEditable(True)  # 设置为可编辑模式，支持手动输入
        self.platform_selector.setPlaceholderText("请手动输入交易平台名称")
        platform_layout.addWidget(platform_label)
        platform_layout.addWidget(self.platform_selector)
        
        save_api_button = QPushButton("保存API配置")
        save_api_button.clicked.connect(self.save_api_settings)
        
        # 添加到表单
        api_layout.addRow(platform_layout)
        api_layout.addRow("API Key:", self.api_key_input)
        api_layout.addRow("API Secret:", self.api_secret_input)
        api_layout.addRow(save_api_button)
        
        api_group.setLayout(api_layout)
        
        # 添加到主布局
        layout.addWidget(account_management_group)
        layout.addLayout(account_display_layout)
        layout.addWidget(account_group)
        layout.addWidget(api_group)
        
        # 刷新账户信息
        refresh_account_button = QPushButton("刷新账户信息")
        refresh_account_button.clicked.connect(self.refresh_account_info)
        layout.addWidget(refresh_account_button)
        
        # 初始化账户信息
        self.refresh_account_info()
        
        return tab
        
    def refresh_account_list(self):
        """刷新账户列表"""
        from utils.account_manager import account_manager
        
        # 清空现有列表
        self.account_list.clear()
        
        # 获取所有账户
        accounts = account_manager.get_all_accounts()
        
        # 添加到下拉列表
        for account_info in accounts:
            account_id = account_info['account_id']
            display_text = f"{account_info['account_name']} ({account_id})"
            self.account_list.addItem(display_text, account_id)
        
        # 优先使用通过对话框选择的账户
        if hasattr(self, 'platform') and hasattr(self, 'account_name') and self.platform and self.account_name:
            for i in range(self.account_list.count()):
                account_id = self.account_list.itemData(i)
                account_info = account_manager.get_account(account_id)
                if account_info and account_info['platform'] == self.platform and account_info['account_name'] == self.account_name:
                    self.account_list.setCurrentIndex(i)
                    self.current_account_display.setText(account_id)
                    return
        
        # 如果没有找到通过对话框选择的账户，使用API集成层的当前账户
        current_account_id = self.api_integration.current_account_id
        for i in range(self.account_list.count()):
            if self.account_list.itemData(i) == current_account_id:
                self.account_list.setCurrentIndex(i)
                break
        
        # 更新当前账户显示
        if self.account_list.currentIndex() >= 0:
            current_account_id = self.account_list.itemData(self.account_list.currentIndex())
            self.current_account_display.setText(current_account_id)
        
    def on_account_changed(self, index):
        """账户切换事件处理"""
        if index >= 0:
            account_id = self.account_list.itemData(index)
            
            # 切换API集成层的当前账户
            if self.api_integration.switch_account(account_id):
                Logger.log_info(f"成功切换到账户: {account_id}")
                self.current_account_display.setText(account_id)
                
                # 刷新账户信息
                self.refresh_account_info()
                
                # 重新创建交易执行器，使用新的API连接器
                current_api_connector = self.api_integration.api_connectors.get(account_id)
                self.trade_executor = TradeExecutor(current_api_connector, self.risk_manager)
                
                # 刷新所有相关数据
                self.update_market_data()
                self.refresh_portfolio()
                
                QMessageBox.information(self, "切换成功", f"已成功切换到账户: {account_id}")
            else:
                QMessageBox.warning(self, "切换失败", f"无法切换到账户: {account_id}")
                # 恢复到之前的账户
                self.refresh_account_list()
                
    def add_account(self):
        """添加新账户"""
        from utils.account_manager import account_manager
        
        # 创建一个简单的对话框用于输入账户信息
        from PyQt5.QtWidgets import QDialog, QFormLayout, QLineEdit, QPushButton, QDialogButtonBox
        
        dialog = QDialog(self)
        dialog.setWindowTitle("添加账户")
        layout = QFormLayout(dialog)
        
        account_name_edit = QLineEdit()
        account_name_edit.setPlaceholderText("输入账户名称")
        
        account_description_edit = QLineEdit()
        account_description_edit.setPlaceholderText("输入账户描述")
        
        platform_selector = QComboBox()
        platform_selector.setEditable(True)  # 设置为可编辑模式，支持手动输入
        platform_selector.setPlaceholderText("请手动输入交易平台名称")
        
        layout.addRow("账户名称:", account_name_edit)
        layout.addRow("账户描述:", account_description_edit)
        layout.addRow("交易平台:", platform_selector)
        
        # 添加按钮
        button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        button_box.accepted.connect(dialog.accept)
        button_box.rejected.connect(dialog.reject)
        layout.addRow(button_box)
        
        if dialog.exec_() == QDialog.Accepted:
            # 获取输入
            account_name = account_name_edit.text().strip()
            account_description = account_description_edit.text().strip()
            platform = platform_selector.currentText()
            
            if not account_name:
                QMessageBox.warning(self, "警告", "账户名称不能为空")
                return
            
            # 生成唯一的账户ID
            import uuid
            account_id = f"account_{uuid.uuid4().hex[:8]}"
            
            # 创建账户信息
            account_info = {
                "account_id": account_id,
                "platform": platform,
                "account_name": account_name,
                "description": account_description
            }
            
            # 添加账户
            # Note: API key and secret are placeholders and should be retrieved from user input
            api_key = "placeholder_key"
            api_secret = "placeholder_secret"
            if account_manager.add_account(
                platform=account_info["platform"],
                account_name=account_info["account_name"],
                api_key=api_key,
                api_secret=api_secret,
                description=account_info["description"]
            ):
                Logger.log_info(f"成功添加账户: {account_id}")
                
                # 刷新账户列表
                self.refresh_account_list()
                
                QMessageBox.information(self, "添加成功", f"已成功添加账户: {account_name}")
            else:
                QMessageBox.warning(self, "添加失败", "无法添加账户")
                
    def remove_account(self):
        """删除账户"""
        from utils.account_manager import account_manager
        
        # 获取当前选中的账户
        current_index = self.account_list.currentIndex()
        if current_index < 0:
            QMessageBox.warning(self, "警告", "请先选择要删除的账户")
            return
        
        account_id = self.account_list.itemData(current_index)
        
        # 不允许删除默认账户
        if account_id == "default":
            QMessageBox.warning(self, "警告", "默认账户不能删除")
            return
        
        # 显示确认对话框
        confirm = QMessageBox.question(
            self, "确认删除", 
            f"确定要删除账户 {account_id} 吗？此操作不可恢复。",
            QMessageBox.Yes | QMessageBox.No, QMessageBox.No
        )
        
        if confirm == QMessageBox.Yes:
            # 删除账户
            if account_manager.remove_account(account_id):
                Logger.log_info(f"成功删除账户: {account_id}")
                
                # 从API集成层移除连接器
                if account_id in self.api_integration.api_connectors:
                    del self.api_integration.api_connectors[account_id]
                
                # 刷新账户列表
                self.refresh_account_list()
                
                QMessageBox.information(self, "删除成功", f"已成功删除账户: {account_id}")
            else:
                QMessageBox.warning(self, "删除失败", "无法删除账户")
                
    def edit_account(self):
        """编辑账户信息"""
        from utils.account_manager import account_manager
        
        # 获取当前选中的账户
        current_index = self.account_list.currentIndex()
        if current_index < 0:
            QMessageBox.warning(self, "警告", "请先选择要编辑的账户")
            return
        
        account_id = self.account_list.itemData(current_index)
        
        # 获取账户信息
        account_info = account_manager.get_account(account_id)
        if not account_info:
            QMessageBox.warning(self, "警告", "无法获取账户信息")
            return
        
        # 创建一个简单的对话框用于编辑账户信息
        from PyQt5.QtWidgets import QDialog, QFormLayout, QLineEdit, QPushButton, QDialogButtonBox, QComboBox
        
        dialog = QDialog(self)
        dialog.setWindowTitle("编辑账户")
        layout = QFormLayout(dialog)
        
        account_name_edit = QLineEdit(account_info.get("account_name", ""))
        account_description_edit = QLineEdit(account_info.get("description", ""))
        
        platform_selector = QComboBox()
        platform_selector.setEditable(True)  # 设置为可编辑模式，支持手动输入
        platform_selector.setPlaceholderText("请手动输入交易平台名称")
        
        # 设置当前平台
        current_platform = account_info.get("platform", "")
        if current_platform:
            platform_selector.setCurrentText(current_platform)
        
        layout.addRow("账户名称:", account_name_edit)
        layout.addRow("账户描述:", account_description_edit)
        layout.addRow("交易平台:", platform_selector)
        
        # 添加按钮
        button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        button_box.accepted.connect(dialog.accept)
        button_box.rejected.connect(dialog.reject)
        layout.addRow(button_box)
        
        if dialog.exec_() == QDialog.Accepted:
            # 获取输入
            account_name = account_name_edit.text().strip()
            account_description = account_description_edit.text().strip()
            platform = platform_selector.currentText()
            
            if not account_name:
                QMessageBox.warning(self, "警告", "账户名称不能为空")
                return
            
            # 更新账户信息
            updated_info = account_info.copy()
            updated_info["account_name"] = account_name
            updated_info["description"] = account_description
            updated_info["platform"] = platform
            
            # 更新账户
            if account_manager.update_account(account_id, updated_info):
                Logger.log_info(f"成功更新账户: {account_id}")
                
                # 刷新账户列表
                self.refresh_account_list()
                
                QMessageBox.information(self, "更新成功", f"已成功更新账户: {account_name}")
            else:
                QMessageBox.warning(self, "更新失败", "无法更新账户")
    
    def load_layout_config(self):
        """加载窗口布局配置"""
        try:
            config_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "layouts", "股票分析系统.json")
            
            if os.path.exists(config_path):
                with open(config_path, 'r', encoding='utf-8') as f:
                    config = json.load(f)
                    
                    # 设置窗口大小和位置
                    if "window_size" in config:
                        size = config["window_size"]
                        self.resize(size["width"], size["height"])
                    
                    if "window_position" in config:
                        pos = config["window_position"]
                        self.move(pos["x"], pos["y"])
                    
                    # 设置表格列宽
                    if "table_columns" in config:
                        columns = config["table_columns"]
                        if "market_table" in columns:
                            for i, width in enumerate(columns["market_table"]):
                                if i < self.market_table.columnCount():
                                    self.market_table.setColumnWidth(i, width)
                
                Logger.log_info(f"成功加载布局配置: {config_path}")
            else:
                Logger.log_warning(f"布局配置文件不存在: {config_path}")
        except Exception as e:
            Logger.log_error(f"加载布局配置失败: {str(e)}")
    
    def save_layout_config(self):
        """保存窗口布局配置"""
        try:
            config = {
                "window_size": {
                    "width": self.width(),
                    "height": self.height()
                },
                "window_position": {
                    "x": self.x(),
                    "y": self.y()
                },
                "table_columns": {
                    "market_table": [self.market_table.columnWidth(i) for i in range(self.market_table.columnCount())]
                }
            }
            
            # 确保layouts目录存在
            layouts_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "layouts")
            if not os.path.exists(layouts_dir):
                os.makedirs(layouts_dir)
            
            config_path = os.path.join(layouts_dir, "股票分析系统.json")
            with open(config_path, 'w', encoding='utf-8') as f:
                json.dump(config, f, ensure_ascii=False, indent=2)
            
            Logger.log_info(f"成功保存布局配置: {config_path}")
        except Exception as e:
            Logger.log_error(f"保存布局配置失败: {str(e)}")
    
    def init_data(self):
        """初始化数据"""
        # 如果提供了账户ID，尝试直接登录该账户并显示全部功能选项卡
        if self.account_id:
            try:
                # 尝试通过API直接切换到指定账户
                from utils.account_manager import account_manager
                
                # 检查账户是否存在
                accounts = account_manager.get_all_accounts()
                target_account = None
                for acc in accounts:
                    if acc.get('account_id') == self.account_id:
                        target_account = acc
                        break
                
                if target_account:
                    # 切换到指定账户
                    account_manager.switch_account(self.account_id)
                    self.api_integration.switch_account(self.account_id)
                    
                    # 动态添加其他选项卡
                    self.trade_tab = self.create_trade_tab()
                    self.portfolio_tab = self.create_portfolio_tab()
                    self.risk_tab = self.create_risk_tab()
                    self.account_tab = self.create_account_tab()
                    
                    # 将选项卡添加到选项卡小部件
                    self.tab_widget.addTab(self.trade_tab, "交易")
                    self.tab_widget.addTab(self.portfolio_tab, "持仓")
                    self.tab_widget.addTab(self.risk_tab, "风险")
                    self.tab_widget.addTab(self.account_tab, "账户")
                    
                    # 刷新账户列表
                    if hasattr(self, 'refresh_account_list'):
                        self.refresh_account_list()
                    
                    # 更新状态栏消息
                    self.statusBar().showMessage(f"已成功登录账户: {target_account.get('account_name')} ({target_account.get('platform')})")
                else:
                    # 如果账户不存在，显示错误信息
                    self.statusBar().showMessage(f"登录失败: 账户ID {self.account_id} 不存在")
            except Exception as e:
                # 记录错误并显示消息
                Logger.log_error(f"账户登录失败: {str(e)}")
                self.statusBar().showMessage(f"账户登录失败: {str(e)}")
        
        # 预加载一些股票数据作为示例，使用真实平台产品代码
        sample_stocks = ["SH600000", "SZ000001", "SH600519", "SZ000858", "SZ002594"]
        
        # 初始化行情表格
        self.market_table.setRowCount(len(sample_stocks))
        
        # 尝试通过API获取真实数据
        try:
            # 获取当前选中的账户ID
            current_index = self.account_list.currentIndex() if hasattr(self, 'account_list') else -1
            account_id = self.account_list.itemData(current_index) if current_index >= 0 else None
            
            # 调用API获取数据
            result = self.api_integration.get_market_data(sample_stocks, account_id=account_id)
            
            # 填充表格数据
            for i, stock_code in enumerate(sample_stocks):
                if stock_code in result:
                    # 使用真实API数据
                    self._update_market_row(i, stock_code, result[stock_code])
                else:
                    # 如果API无法获取数据，仅显示代码，不使用模拟数据
                    code_item = QTableWidgetItem(stock_code)
                    name_item = QTableWidgetItem(stock_code)  # 使用代码作为名称，不添加虚拟前缀
                    price_item = QTableWidgetItem("--")
                    change_item = QTableWidgetItem("--")
                    open_item = QTableWidgetItem("--")
                    high_item = QTableWidgetItem("--")
                    low_item = QTableWidgetItem("--")
                    volume_item = QTableWidgetItem("--")
                    amount_item = QTableWidgetItem("--")
                    turnover_item = QTableWidgetItem("--")
                    time_item = QTableWidgetItem(datetime.now().strftime('%H:%M:%S'))
                    
                    # 设置居中对齐
                    for item in [code_item, name_item, price_item, change_item, open_item, high_item, 
                                 low_item, volume_item, amount_item, turnover_item, time_item]:
                        item.setTextAlignment(Qt.AlignCenter)
                    
                    # 添加到表格
                    self.market_table.setItem(i, 0, code_item)
                    self.market_table.setItem(i, 1, name_item)
                    self.market_table.setItem(i, 2, price_item)
                    self.market_table.setItem(i, 3, change_item)
                    self.market_table.setItem(i, 4, open_item)
                    self.market_table.setItem(i, 5, high_item)
                    self.market_table.setItem(i, 6, low_item)
                    self.market_table.setItem(i, 7, volume_item)
                    self.market_table.setItem(i, 8, amount_item)
                    self.market_table.setItem(i, 9, turnover_item)
                    self.market_table.setItem(i, 10, time_item)
        except Exception as e:
            Logger.log_error(f"初始化市场数据失败: {str(e)}")
            # 如果API调用失败，仅显示股票代码，不使用模拟数据
            for i, stock_code in enumerate(sample_stocks):
                code_item = QTableWidgetItem(stock_code)
                name_item = QTableWidgetItem(stock_code)  # 使用代码作为名称，不添加虚拟前缀
                price_item = QTableWidgetItem("--")
                change_item = QTableWidgetItem("--")
                open_item = QTableWidgetItem("--")
                high_item = QTableWidgetItem("--")
                low_item = QTableWidgetItem("--")
                volume_item = QTableWidgetItem("--")
                amount_item = QTableWidgetItem("--")
                turnover_item = QTableWidgetItem("--")
                time_item = QTableWidgetItem(datetime.now().strftime('%H:%M:%S'))
                
                # 设置居中对齐
                for item in [code_item, name_item, price_item, change_item, open_item, high_item, 
                             low_item, volume_item, amount_item, turnover_item, time_item]:
                    item.setTextAlignment(Qt.AlignCenter)
                
                # 添加到表格
                self.market_table.setItem(i, 0, code_item)
                self.market_table.setItem(i, 1, name_item)
                self.market_table.setItem(i, 2, price_item)
                self.market_table.setItem(i, 3, change_item)
                self.market_table.setItem(i, 4, open_item)
                self.market_table.setItem(i, 5, high_item)
                self.market_table.setItem(i, 6, low_item)
                self.market_table.setItem(i, 7, volume_item)
                self.market_table.setItem(i, 8, amount_item)
                self.market_table.setItem(i, 9, turnover_item)
                self.market_table.setItem(i, 10, time_item)
    
    def on_product_type_changed(self, index):
        """当产品类型改变时更新UI"""
        product_type = self.product_type_selector.currentData()
        
        # 根据产品类型更新提示文本
        if product_type == "stock":
            self.stock_code_input.setPlaceholderText("输入股票代码，如：SH600000")
        elif product_type == "fund":
            self.stock_code_input.setPlaceholderText("输入基金代码，如：161725")
        elif product_type == "bond":
            self.stock_code_input.setPlaceholderText("输入债券代码，如：110003")
        elif product_type == "future":
            self.stock_code_input.setPlaceholderText("输入期货代码，如：CU2308")
        
        # 清空输入框
        self.stock_code_input.clear()
    
    def query_stock(self):
        """查询产品信息"""
        product_code = self.stock_code_input.text().strip().upper()
        product_type = self.product_type_selector.currentData()
        
        if not product_code:
            QMessageBox.warning(self, "警告", "请输入产品代码")
            return
        
        # 显示加载状态
        self.statusBar().showMessage(f"正在查询 {product_code} 的行情数据...")
        
        try:
            # 调用API获取数据
            result = None
            
            # 首先尝试通过API获取真实数据
            if product_type == "stock":
                result = self.api_integration.get_market_data(product_code)
            else:
                # 对于非股票类型，也尝试使用API获取，如果API不支持则返回None
                result = self.api_integration.get_market_data(product_code)
            
            if result and product_code in result:
                data = result[product_code]
                
                # 检查是否已存在该产品
                found = False
                for row in range(self.market_table.rowCount()):
                    item = self.market_table.item(row, 0)
                    if item and item.text() == product_code:
                        # 更新现有行
                        self._update_market_row(row, product_code, data, product_type)
                        found = True
                        break
                
                if not found:
                    # 添加新行
                    row = self.market_table.rowCount()
                    self.market_table.setRowCount(row + 1)
                    self._update_market_row(row, product_code, data, product_type)
                
                # 成功消息
                self.statusBar().showMessage(f"成功获取 {product_code} 的行情数据")
            else:
                # 无法获取行情数据时，只显示错误信息
                QMessageBox.warning(
                    self, 
                    "查询失败", 
                    f"无法获取 {product_code} 的行情数据\n\n请检查网络连接或产品代码是否正确。"
                )
                self.statusBar().showMessage("就绪")
        except Exception as e:
            # API连接失败时，显示实际错误信息
            QMessageBox.warning(
                self, 
                "查询失败", 
                f"查询过程中发生错误: {str(e)}\n\n请检查网络连接或API配置。"
            )
            self.statusBar().showMessage("就绪")
    
    def _get_mock_product_data(self, product_code, product_type):
        """为非股票类型的产品生成模拟数据 - 此方法已废弃"""
        Logger.log_warning("_get_mock_product_data方法已废弃，不应再被调用")
        return None
    
    def get_product_type_label(self, product_type):
        """获取产品类型的中文标签"""
        type_labels = {
            "stock": "股票",
            "fund": "基金",
            "bond": "债券",
            "future": "期货"
        }
        return type_labels.get(product_type, "产品")
    
    def _update_market_row(self, row, product_code, data, product_type="stock"):
        """更新行情表格中的一行数据"""
        # 从数据中提取字段，使用数据中提供的值，不使用虚拟名称
        product_name = data.get("stock_name", "") if product_type == "stock" else \
                      data.get("fund_name", "") if product_type == "fund" else \
                      data.get("bond_name", "") if product_type == "bond" else \
                      data.get("future_name", "") if product_type == "future" else ""
        
        # 确保所有必填字段都存在
        if not product_name:
            product_name = product_code  # 使用代码作为名称，不添加虚拟前缀
            
        current_price = data.get("current_price", 0.0)
        prev_close = data.get("prev_close", current_price)
        change_percent = ((current_price - prev_close) / prev_close * 100) if prev_close > 0 else 0.0
        open_price = data.get("open_price", current_price)
        high_price = data.get("high_price", current_price)
        low_price = data.get("low_price", current_price)
        volume = data.get("volume", 0) / 10000  # 转换为万
        amount = data.get("amount", 0) / 10000  # 转换为万
        turnover = data.get("turnover", 0.0)
        update_time = data.get("timestamp", datetime.now().strftime('%H:%M:%S'))
        
        # 创建表格项
        code_item = QTableWidgetItem(product_code)
        name_item = QTableWidgetItem(product_name)
        price_item = QTableWidgetItem(f"{current_price:.2f}")
        change_item = QTableWidgetItem(f"{change_percent:.2f}%")
        open_item = QTableWidgetItem(f"{open_price:.2f}")
        high_item = QTableWidgetItem(f"{high_price:.2f}")
        low_item = QTableWidgetItem(f"{low_price:.2f}")
        volume_item = QTableWidgetItem(f"{volume:.2f}")
        amount_item = QTableWidgetItem(f"{amount:.2f}")
        turnover_item = QTableWidgetItem(f"{turnover:.2f}%")
        time_item = QTableWidgetItem(update_time)
        
        # 设置涨跌幅颜色
        if change_percent > 0:
            change_item.setForeground(QBrush(QColor(255, 0, 0)))
        elif change_percent < 0:
            change_item.setForeground(QBrush(QColor(0, 128, 0)))
        
        # 设置居中对齐
        for item in [code_item, name_item, price_item, change_item, open_item, high_item, 
                     low_item, volume_item, amount_item, turnover_item, time_item]:
            item.setTextAlignment(Qt.AlignCenter)
        
        # 添加到表格
        self.market_table.setItem(row, 0, code_item)
        self.market_table.setItem(row, 1, name_item)
        self.market_table.setItem(row, 2, price_item)
        self.market_table.setItem(row, 3, change_item)
        self.market_table.setItem(row, 4, open_item)
        self.market_table.setItem(row, 5, high_item)
        self.market_table.setItem(row, 6, low_item)
        self.market_table.setItem(row, 7, volume_item)
        self.market_table.setItem(row, 8, amount_item)
        self.market_table.setItem(row, 9, turnover_item)
        self.market_table.setItem(row, 10, time_item)
    
    def update_market_data(self):
        """定时更新行情数据"""
        try:
            # 获取当前选中的账户ID
            current_index = self.account_list.currentIndex()
            if current_index < 0:
                Logger.log_warning("没有选中的账户")
                return
                
            account_id = self.account_list.itemData(current_index)
            
            # 获取当前表格中的所有股票代码
            stock_codes = []
            for row in range(self.market_table.rowCount()):
                item = self.market_table.item(row, 0)
                if item:
                    stock_codes.append(item.text())
            
            if stock_codes:
                # 调用API获取数据，明确传递账户ID
                result = self.api_integration.get_market_data(stock_codes, account_id=account_id)
                
                if result:
                    # 更新表格数据
                    for row in range(self.market_table.rowCount()):
                        item = self.market_table.item(row, 0)
                        if item:
                            stock_code = item.text()
                            if stock_code in result:
                                self._update_market_row(row, stock_code, result[stock_code])
                    
                    # 更新状态栏
                    self.statusBar().showMessage(f"行情数据已更新于 {datetime.now().strftime('%H:%M:%S')}")
        except Exception as e:
            Logger.log_error(f"更新行情数据失败: {str(e)}")
    
    def submit_order(self):
        """提交订单"""
        # 获取当前选中的账户ID
        current_index = self.account_list.currentIndex()
        if current_index < 0:
            QMessageBox.warning(self, "警告", "请先选择一个账户")
            Logger.log_warning("没有选中的账户")
            return
            
        account_id = self.account_list.itemData(current_index)
        
        # 检查交易执行器是否已初始化
        if self.trade_executor is None:
            QMessageBox.warning(self, "警告", "交易执行器尚未初始化，请稍后再试")
            return
        
        stock_code = self.trade_stock_code.text().strip().upper()
        order_type = "buy" if self.trade_order_type.currentText() == "买入" else "sell"
        quantity = self.trade_quantity.value()
        price = self.trade_price.value()
        
        # 验证输入
        if not stock_code:
            QMessageBox.warning(self, "警告", "请输入股票代码")
            return
        
        if quantity <= 0:
            QMessageBox.warning(self, "警告", "交易数量必须大于0")
            return
        
        if price <= 0:
            QMessageBox.warning(self, "警告", "交易价格必须大于0")
            return
        
        # 显示确认对话框
        confirm = QMessageBox.question(
            self, "确认交易", 
            f"确定要{self.trade_order_type.currentText()}\n股票代码: {stock_code}\n数量: {quantity}股\n价格: {price:.2f}元/股\n总金额: {price * quantity:.2f}元",
            QMessageBox.Yes | QMessageBox.No, QMessageBox.No
        )
        
        if confirm != QMessageBox.Yes:
            return
        
        # 显示加载状态
        self.statusBar().showMessage(f"正在提交订单...")
        
        try:
            # 调用交易执行器下单，明确传递账户ID
            result = self.trade_executor.place_order(stock_code, order_type, quantity, price, account_id=account_id)
            
            if result and result.get("success", False):
                # 获取订单信息
                order_id = result.get("order_id")
                order_info = result.get("order_info", {})
                
                # 添加到订单表格
                row = self.orders_table.rowCount()
                self.orders_table.setRowCount(row + 1)
                
                # 创建表格项
                id_item = QTableWidgetItem(order_id)
                code_item = QTableWidgetItem(stock_code)
                type_item = QTableWidgetItem("买入" if order_type == "buy" else "卖出")
                qty_item = QTableWidgetItem(str(quantity))
                price_item = QTableWidgetItem(f"{price:.2f}")
                status_item = QTableWidgetItem(order_info.get("status", "pending"))
                time_item = QTableWidgetItem(order_info.get("create_time", datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
                
                # 设置居中对齐
                for item in [id_item, code_item, type_item, qty_item, price_item, status_item, time_item]:
                    item.setTextAlignment(Qt.AlignCenter)
                
                # 添加到表格
                self.orders_table.setItem(row, 0, id_item)
                self.orders_table.setItem(row, 1, code_item)
                self.orders_table.setItem(row, 2, type_item)
                self.orders_table.setItem(row, 3, qty_item)
                self.orders_table.setItem(row, 4, price_item)
                self.orders_table.setItem(row, 5, status_item)
                self.orders_table.setItem(row, 6, time_item)
                
                # 成功消息
                QMessageBox.information(self, "下单成功", f"订单已提交，订单号: {order_id}")
                self.statusBar().showMessage(f"下单成功，订单号: {order_id}")
                
                # 刷新持仓
                self.refresh_portfolio()
            else:
                message = result.get("message", "下单失败") if result else "下单失败"
                QMessageBox.warning(self, "下单失败", message)
                self.statusBar().showMessage("就绪")
        except Exception as e:
            QMessageBox.critical(self, "错误", f"下单过程中发生错误: {str(e)}")
            self.statusBar().showMessage("就绪")
    
    def cancel_selected_order(self):
        """取消选中的订单"""
        # 获取当前选中的账户ID
        current_index = self.account_list.currentIndex()
        if current_index < 0:
            QMessageBox.warning(self, "警告", "请先选择一个账户")
            Logger.log_warning("没有选中的账户")
            return
            
        account_id = self.account_list.itemData(current_index)
        
        # 检查交易执行器是否已初始化
        if self.trade_executor is None:
            QMessageBox.warning(self, "警告", "交易执行器尚未初始化，请稍后再试")
            return
        
        selected_rows = self.orders_table.selectionModel().selectedRows()
        
        if not selected_rows:
            QMessageBox.warning(self, "警告", "请先选中要取消的订单")
            return
        
        # 获取选中行的订单ID
        row = selected_rows[0].row()
        order_id_item = self.orders_table.item(row, 0)
        
        if not order_id_item:
            QMessageBox.warning(self, "警告", "无法获取订单ID")
            return
        
        order_id = order_id_item.text()
        
        # 显示确认对话框
        confirm = QMessageBox.question(
            self, "确认取消", 
            f"确定要取消订单 {order_id}?",
            QMessageBox.Yes | QMessageBox.No, QMessageBox.No
        )
        
        if confirm != QMessageBox.Yes:
            return
        
        # 显示加载状态
        self.statusBar().showMessage(f"正在取消订单...")
        
        try:
            # 调用交易执行器取消订单，明确传递账户ID
            result = self.trade_executor.cancel_order(order_id, account_id=account_id)
            
            if result:
                # 更新订单状态
                status_item = QTableWidgetItem("已取消")
                status_item.setTextAlignment(Qt.AlignCenter)
                self.orders_table.setItem(row, 5, status_item)
                
                # 成功消息
                QMessageBox.information(self, "取消成功", f"订单 {order_id} 已取消")
                self.statusBar().showMessage(f"订单 {order_id} 已取消")
            else:
                QMessageBox.warning(self, "取消失败", f"订单 {order_id} 取消失败")
                self.statusBar().showMessage("就绪")
        except Exception as e:
            QMessageBox.critical(self, "错误", f"取消订单过程中发生错误: {str(e)}")
            self.statusBar().showMessage("就绪")
    
    def refresh_portfolio(self):
        """刷新持仓信息"""
        # 显示加载状态
        self.statusBar().showMessage("正在刷新持仓信息...")
        
        try:
            # 获取当前选中的账户ID
            current_index = self.account_list.currentIndex()
            if current_index < 0:
                Logger.log_warning("没有选中的账户")
                self.statusBar().showMessage("就绪")
                return
                
            account_id = self.account_list.itemData(current_index)
            
            # 获取真实持仓数据，明确传递账户ID
            positions = self.api_integration.get_positions(account_id=account_id)
            
            # 清空表格
            self.portfolio_table.setRowCount(0)
            
            if positions:
                # 添加持仓数据
                for i, (stock_code, position_data) in enumerate(positions.items()):
                    # 使用真实数据，不使用虚拟名称
                    stock_name = position_data.get("stock_name", stock_code)  # 如果没有名称，使用代码
                    quantity = position_data.get("quantity", 0)
                    cost_price = position_data.get("cost_price", 0.0)
                    current_price = position_data.get("current_price", 0.0)
                    market_value = quantity * current_price
                    profit = quantity * (current_price - cost_price)
                    profit_rate = (profit / (quantity * cost_price) * 100) if (quantity * cost_price) > 0 else 0.0
                    update_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                    
                    # 创建新行
                    row = self.portfolio_table.rowCount()
                    self.portfolio_table.setRowCount(row + 1)
                    
                    # 创建表格项
                    code_item = QTableWidgetItem(stock_code)
                    name_item = QTableWidgetItem(stock_name)
                    qty_item = QTableWidgetItem(str(quantity))
                    cost_item = QTableWidgetItem(f"{cost_price:.2f}")
                    price_item = QTableWidgetItem(f"{current_price:.2f}")
                    value_item = QTableWidgetItem(f"{market_value:.2f}")
                    profit_item = QTableWidgetItem(f"{profit:.2f}")
                    rate_item = QTableWidgetItem(f"{profit_rate:.2f}%")
                    time_item = QTableWidgetItem(update_time)
                    
                    # 设置盈亏颜色
                    if profit > 0:
                        profit_item.setForeground(QBrush(QColor(255, 0, 0)))
                        rate_item.setForeground(QBrush(QColor(255, 0, 0)))
                    elif profit < 0:
                        profit_item.setForeground(QBrush(QColor(0, 128, 0)))
                        rate_item.setForeground(QBrush(QColor(0, 128, 0)))
                    
                    # 设置居中对齐
                    for item in [code_item, name_item, qty_item, cost_item, price_item, 
                                 value_item, profit_item, rate_item, time_item]:
                        item.setTextAlignment(Qt.AlignCenter)
                    
                    # 添加到表格
                    self.portfolio_table.setItem(row, 0, code_item)
                    self.portfolio_table.setItem(row, 1, name_item)
                    self.portfolio_table.setItem(row, 2, qty_item)
                    self.portfolio_table.setItem(row, 3, cost_item)
                    self.portfolio_table.setItem(row, 4, price_item)
                    self.portfolio_table.setItem(row, 5, value_item)
                    self.portfolio_table.setItem(row, 6, profit_item)
                    self.portfolio_table.setItem(row, 7, rate_item)
                    self.portfolio_table.setItem(row, 8, time_item)
            
            # 刷新账户信息
            self.refresh_account_info()
            
            self.statusBar().showMessage("持仓信息已更新")
        except Exception as e:
            QMessageBox.critical(self, "错误", f"刷新持仓过程中发生错误: {str(e)}")
            self.statusBar().showMessage("就绪")
    
    def load_risk_settings(self):
        """加载风险设置"""
        # 从风险管理器获取当前设置
        risk_rules = self.risk_manager.risk_rules
        
        # 更新界面控件
        self.max_position_per_stock.setValue(risk_rules.get("max_position_per_stock", 100000))
        self.max_single_order.setValue(risk_rules.get("max_single_order", 50000))
        self.daily_trading_limit.setValue(risk_rules.get("daily_trading_limit", 200000))
        self.max_position_percentage.setValue(risk_rules.get("max_position_percentage", 0.3))
    
    def save_risk_settings(self):
        """保存风险设置"""
        # 获取界面控件的值
        new_rules = {
            "max_position_per_stock": self.max_position_per_stock.value(),
            "max_single_order": self.max_single_order.value(),
            "daily_trading_limit": self.daily_trading_limit.value(),
            "max_position_percentage": self.max_position_percentage.value()
        }
        
        try:
            # 更新风险管理器的规则
            for key, value in new_rules.items():
                if key in self.risk_manager.risk_rules:
                    self.risk_manager.risk_rules[key] = value
            
            # 保存到配置文件
            config_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "config", "risk_rules.json")
            
            # 确保config目录存在
            config_dir = os.path.dirname(config_path)
            if not os.path.exists(config_dir):
                os.makedirs(config_dir)
            
            # 写入配置文件
            with open(config_path, 'w', encoding='utf-8') as f:
                json.dump(new_rules, f, ensure_ascii=False, indent=2)
            
            QMessageBox.information(self, "保存成功", "风险设置已保存")
            Logger.log_info(f"成功保存风险设置到: {config_path}")
        except Exception as e:
            QMessageBox.critical(self, "错误", f"保存风险设置失败: {str(e)}")
            Logger.log_error(f"保存风险设置失败: {str(e)}")
    
    def refresh_account_info(self):
        """刷新账户信息"""
        try:
            # 检查必要的UI元素是否已创建
            if not hasattr(self, 'total_asset') or not hasattr(self, 'available_cash') or \
               not hasattr(self, 'market_value') or not hasattr(self, 'total_profit') or \
               not hasattr(self, 'profit_rate'):
                Logger.log_warning("账户信息UI元素尚未创建，推迟刷新")
                return
                
            # 获取当前选中的账户ID
            current_index = self.account_list.currentIndex()
            if current_index < 0:
                Logger.log_warning("没有选中的账户")
                return
                
            account_id = self.account_list.itemData(current_index)
            
            # 获取真实账户数据，明确传递账户ID
            account_info = self.api_integration.get_account_info(account_id=account_id)
            
            if account_info:
                # 更新账户信息
                total_asset = account_info.get("total_asset", 0.0)
                available_cash = account_info.get("available_cash", 0.0)
                market_value = account_info.get("market_value", 0.0)
                total_profit = account_info.get("total_profit", 0.0)
                profit_rate = account_info.get("profit_rate", 0.0)
                
                # 更新界面
                self.total_asset.setText(f"{total_asset:.2f} 元")
                self.available_cash.setText(f"{available_cash:.2f} 元")
                self.market_value.setText(f"{market_value:.2f} 元")
                
                # 设置盈亏颜色
                profit_text = f"{total_profit:.2f} 元"
                rate_text = f"{profit_rate:.2f}%"
                
                if total_profit > 0:
                    self.total_profit.setStyleSheet("color: red;")
                    self.profit_rate.setStyleSheet("color: red;")
                elif total_profit < 0:
                    self.total_profit.setStyleSheet("color: green;")
                    self.profit_rate.setStyleSheet("color: green;")
                else:
                    self.total_profit.setStyleSheet("")
                    self.profit_rate.setStyleSheet("")
                
                self.total_profit.setText(profit_text)
                self.profit_rate.setText(rate_text)
            else:
                # 如果无法获取账户信息，显示为空而不是使用模拟数据
                self.total_asset.setText("0.00 元")
                self.available_cash.setText("0.00 元")
                self.market_value.setText("0.00 元")
                self.total_profit.setText("0.00 元")
                self.profit_rate.setText("0.00%")
                self.total_profit.setStyleSheet("")
                self.profit_rate.setStyleSheet("")
        except Exception as e:
            Logger.log_error(f"刷新账户信息失败: {str(e)}")
    
    def save_api_settings(self):
        """保存API设置"""
        api_key = self.api_key_input.text().strip()
        api_secret = self.api_secret_input.text().strip()
        platform = self.platform_selector.currentText()
        
        if not api_key or not api_secret:
            QMessageBox.warning(self, "警告", "API Key和API Secret不能为空")
            return
        
        # 获取当前选中的账户ID
        current_index = self.account_list.currentIndex()
        if current_index < 0:
            QMessageBox.warning(self, "警告", "请先选择一个账户")
            return
        
        account_id = self.account_list.itemData(current_index)
        
        # 显示确认对话框
        confirm = QMessageBox.question(
            self, "确认保存", 
            f"确定要为账户 '{account_id}' 保存API配置吗？",
            QMessageBox.Yes | QMessageBox.No, QMessageBox.No
        )
        
        if confirm != QMessageBox.Yes:
            return
        
        # 显示加载状态
        self.statusBar().showMessage(f"正在为账户 {account_id} 保存API配置...")
        
        try:
            # 更新账户信息中的平台
            from utils.account_manager import account_manager
            account_info = account_manager.get_account(account_id)
            if account_info:
                account_info['platform'] = platform
                account_manager.update_account(account_id, account_info)
            
            # 调用API集成保存凭证
            result = self.api_integration.save_api_credentials(api_key, api_secret, account_id)
            
            if result:
                # 更新API连接器，使用新的凭证
                self.api_integration.initialize_api_connector(account_id)
                
                QMessageBox.information(self, "保存成功", f"账户 '{account_id}' 的API配置已保存")
                self.statusBar().showMessage(f"账户 '{account_id}' 的API配置已保存")
            else:
                QMessageBox.warning(self, "保存失败", f"账户 '{account_id}' 的API配置保存失败")
                self.statusBar().showMessage("就绪")
        except Exception as e:
            QMessageBox.critical(self, "错误", f"保存API配置过程中发生错误: {str(e)}")
            self.statusBar().showMessage("就绪")
    
    def generate_product_analysis(self):
        """生成产品分析报告"""
        # 获取输入的产品代码和类型
        product_code = self.stock_code_input.text().strip()
        product_type = self.product_type_selector.currentData()
        
        if not product_code:
            QMessageBox.warning(self, "警告", "请先输入产品代码")
            return
        
        try:
            # 显示加载状态
            self.statusBar().showMessage(f"正在生成{product_code}的分析报告...")
            
            # 生成分析报告数据，传递产品类型参数
            analysis_result = self.product_analysis.generate_analysis_report(product_code, product_type=product_type)
            
            if not analysis_result.get("success", False):
                raise Exception(analysis_result.get("error", "生成分析报告数据失败"))
            
            # 生成HTML报告内容
            report_html = self.product_analysis._generate_html_report(analysis_result)
            
            # 显示分析报告
            self.show_analysis_report(report_html, product_code)
            
            self.statusBar().showMessage(f"{product_code}的分析报告已生成")
        except Exception as e:
            QMessageBox.critical(self, "错误", f"生成分析报告失败: {str(e)}")
            Logger.log_error(f"生成分析报告失败: {str(e)}")
            self.statusBar().showMessage("就绪")
    
    def show_analysis_report(self, report_html, stock_code):
        """显示分析报告"""
        # 检查是否已经存在分析报告选项卡
        report_tab_index = -1
        for i in range(self.tab_widget.count()):
            if self.tab_widget.tabText(i) == f"{stock_code}分析报告":
                report_tab_index = i
                break
        
        # 创建分析报告选项卡
        if report_tab_index == -1:
            report_tab = QWidget()
            layout = QVBoxLayout(report_tab)
            
            # 添加文本浏览器用于显示HTML报告
            self.report_browser = QTextBrowser()
            self.report_browser.setOpenExternalLinks(True)
            
            # 添加导出按钮
            export_layout = QHBoxLayout()
            export_layout.addStretch()
            
            # 导出HTML按钮
            export_html_button = QPushButton("导出HTML报告")
            export_html_button.clicked.connect(lambda: self.export_report(report_html, stock_code, "html"))
            export_layout.addWidget(export_html_button)
            
            # 导出PDF按钮
            export_pdf_button = QPushButton("导出PDF报告")
            export_pdf_button.clicked.connect(lambda: self.export_report(report_html, stock_code, "pdf"))
            export_layout.addWidget(export_pdf_button)
            
            # 添加到主布局
            layout.addWidget(self.report_browser)
            layout.addLayout(export_layout)
            
            # 添加到选项卡
            report_tab_index = self.tab_widget.addTab(report_tab, f"{stock_code}分析报告")
        
        # 显示报告内容
        self.report_browser.setHtml(report_html)
        
        # 切换到分析报告选项卡
        self.tab_widget.setCurrentIndex(report_tab_index)
    
    def export_report(self, report_content, stock_code, export_type="html"):
        """导出分析报告"""
        try:
            Logger.log_info(f"开始导出分析报告: 股票代码={stock_code}, 导出类型={export_type}")
            
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            filename = f"{stock_code}_分析报告_{timestamp}"
            
            # 选择一个确保可写的导出目录策略
            # 1. 首先尝试用户桌面目录 - 最可靠的可写位置
            user_dir = os.path.expanduser("~")
            desktop_dir = os.path.join(user_dir, "Desktop")
            
            # 设置导出目录
            exports_dir = os.path.join(desktop_dir, "ProfessionalStockAnalysis_Exports")
            
            try:
                Logger.log_info(f"尝试在桌面创建导出目录: {exports_dir}")
                os.makedirs(exports_dir, exist_ok=True)
                Logger.log_info(f"成功创建/访问导出目录: {exports_dir}")
            except Exception as inner_e:
                Logger.log_error(f"无法在桌面创建导出目录: {str(inner_e)}")
                # 如果桌面也无法创建，尝试使用当前工作目录作为最后的备选
                current_dir = os.getcwd()
                exports_dir = os.path.join(current_dir, "exports")
                Logger.log_info(f"尝试使用当前工作目录: {current_dir}")
                os.makedirs(exports_dir, exist_ok=True)
                Logger.log_info(f"成功创建/访问备选导出目录: {exports_dir}")
            
            # 导出HTML报告
            if export_type == "html":
                file_path = os.path.join(exports_dir, f"{filename}.html")
                Logger.log_info(f"准备导出HTML报告到路径: {file_path}")
                
                # 写入文件
                try:
                    with open(file_path, 'w', encoding='utf-8') as f:
                        f.write(report_content)
                    Logger.log_info(f"HTML报告成功导出到: {file_path}")
                except Exception as write_e:
                    Logger.log_error(f"写入报告文件失败: {str(write_e)}")
                    # 如果写入失败，尝试使用简单文件名和桌面直接路径
                    fallback_path = os.path.join(desktop_dir, f"{stock_code}_report.html")
                    Logger.log_info(f"尝试使用备选路径: {fallback_path}")
                    with open(fallback_path, 'w', encoding='utf-8') as f:
                        f.write(report_content)
                    file_path = fallback_path
                    Logger.log_info(f"HTML报告成功导出到备选路径: {file_path}")
                
                # 显示成功消息并询问是否打开目录
                response = QMessageBox.information(
                    self, 
                    "导出成功", 
                    f"HTML报告已保存至:\n{file_path}\n\n是否打开报告所在文件夹?",
                    QMessageBox.Yes | QMessageBox.No
                )
                
                # 如果用户选择打开目录
                if response == QMessageBox.Yes:
                    try:
                        # 打开包含报告的文件夹
                        os.startfile(exports_dir)
                        Logger.log_info(f"已打开报告所在文件夹: {exports_dir}")
                    except:
                        Logger.log_error("无法打开文件夹")
                        # 尝试直接打开报告文件
                        try:
                            webbrowser.open(file_path)
                            Logger.log_info(f"已直接打开报告文件: {file_path}")
                        except:
                            Logger.log_error("无法打开报告文件")
            
            # 导出PDF报告（简化实现）
            elif export_type == "pdf":
                file_path = os.path.join(exports_dir, f"{filename}.pdf")
                Logger.log_info(f"准备导出PDF报告到路径: {file_path}")
                
                # 简化实现，仅写入文本内容
                with open(file_path, 'w', encoding='utf-8') as f:
                    f.write("PDF报告生成功能正在开发中")
                
                Logger.log_info(f"PDF报告成功导出到: {file_path}")
                
                # 显示成功消息并询问是否打开目录
                response = QMessageBox.information(
                    self, 
                    "导出成功", 
                    f"PDF报告已保存至:\n{file_path}\n\n注意：当前为简化实现，完整功能正在开发中。\n\n是否打开报告所在文件夹?",
                    QMessageBox.Yes | QMessageBox.No
                )
                
                # 如果用户选择打开目录
                if response == QMessageBox.Yes:
                    try:
                        os.startfile(exports_dir)
                        Logger.log_info(f"已打开报告所在文件夹: {exports_dir}")
                    except:
                        Logger.log_error("无法打开文件夹")
        except Exception as e:
            Logger.log_error(f"导出报告失败: {str(e)}", exc_info=True)
            QMessageBox.critical(self, "导出失败", f"导出报告时发生错误: {str(e)}")
    
    def closeEvent(self, event):
        """窗口关闭事件处理"""
        # 保存布局配置
        self.save_layout_config()
        
        # 关闭所有API连接
        # APIIntegration使用api_connectors字典管理多个账户的连接器
        for account_id, connector in self.api_integration.api_connectors.items():
            # 由于TencentAPIConnector没有提供close方法，我们记录日志表示连接已关闭
            Logger.log_info(f"关闭账户 {account_id} 的API连接")
        
        # 清理自动升级系统资源
        self.update_manager.cleanup()
        
        # 清理反侦查系统资源
        self.detection_manager.cleanup()
        
        # 继续关闭窗口
        event.accept()

def show_account_input_dialog(parent=None, account_id=None):
    """显示账户输入对话框，如果提供了account_id则直接返回对应账户信息"""
    from PyQt5.QtWidgets import QDialog, QFormLayout, QLineEdit, QComboBox, QPushButton, QDialogButtonBox, QMessageBox
    from PyQt5.QtCore import Qt
    from utils.account_manager import account_manager
    import datetime
    
    # 如果提供了account_id，直接返回账户信息
    if account_id:
        account_info = account_manager.get_account(account_id)
        if account_info:
            return account_info.get("platform", "tencent"), account_info.get("account_name", ""), account_id
    
    # 创建对话框
    dialog = QDialog(parent)
    dialog.setWindowTitle("请输入您的证券账户")
    dialog.setMinimumWidth(400)
    layout = QFormLayout(dialog)
    
    # 创建输入字段
    platform_selector = QComboBox()
    platform_selector.setEditable(True)  # 设置为可编辑模式，支持手动输入
    platform_selector.setPlaceholderText("请手动输入交易平台名称")
    
    # 添加一些常见平台选项
    common_platforms = ["tencent", "招商证券", "华泰证券", "国金证券", "中信证券", "银河证券"]
    platform_selector.addItems(common_platforms)
    
    # 默认选择tencent
    platform_selector.setCurrentText("tencent")
    
    account_name_edit = QLineEdit()
    account_name_edit.setPlaceholderText("请输入账户名称或卡号")
    
    # 添加到布局
    layout.addRow("交易平台:", platform_selector)
    layout.addRow("输入账户名称或卡号:", account_name_edit)
    
    # 添加按钮
    button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
    button_box.accepted.connect(dialog.accept)
    button_box.rejected.connect(dialog.reject)
    layout.addRow(button_box)
    
    # 显示对话框并获取结果
    if dialog.exec_() == QDialog.Accepted:
        platform = platform_selector.currentText()
        account_name = account_name_edit.text().strip()
        
        if not account_name:
            QMessageBox.warning(dialog, "警告", "账户名称不能为空")
            return show_account_input_dialog(parent)
        
        # 查找或创建账户
        try:
            # 尝试查找账户
            accounts = account_manager.get_all_accounts()
            found_account = None
            for acc_id, acc_info in accounts.items():
                if acc_info.get("account_name") == account_name or acc_id == account_name:
                    found_account = acc_info
                    found_account["account_id"] = acc_id
                    break
            
            if found_account:
                return platform, account_name, found_account["account_id"]
            else:
                # 创建新账户
                account_id = f"{platform}_{datetime.datetime.now().strftime('%Y%m%d%H%M%S')}"
                account_manager.add_account(
                    platform=platform,
                    account_id=account_id,
                    account_name=account_name,
                    api_key="",
                    api_secret="",
                    description=f"{platform}平台账户"
                )
                return platform, account_name, account_id
        except Exception:
            # 如果账户管理功能不可用，仅返回平台和账户名称
            return platform, account_name, None
    
    return None, None, None

def main(account_id=None):
    """应用程序入口"""
    import sys
    # 创建应用程序实例
    app = QApplication(sys.argv)
    
    # 显示账户输入对话框
    platform, account_name, account_id = show_account_input_dialog(account_id=account_id)
    
    if platform and account_name:
        # 创建并显示主窗口
        window = MainWindow(platform=platform, account_name=account_name, account_id=account_id)
        window.show()
        
        # 运行应用程序
        sys.exit(app.exec_())
    else:
        sys.exit(0)

if __name__ == "__main__":
    # 检查命令行参数是否包含account_id
    account_id = None
    if len(sys.argv) > 1:
        account_id = sys.argv[1]
    main(account_id=account_id)